import sys
sys.path.append('..')
from mapping.GuaCombination import GuaCombination
from core.create import build_dict
from core.time.handle_time import get_time_info
from core.time.build_time import build_event_time
from core.validation.valid_gua_dict import validate_gua_dict
from utils.attr_dict import AttrFuncDict
from mapping.GuaModel import GuaModel
from constants import GAN, LIU_QIN, WX, ZHI, ZHI_TO_WX


class LiuYaoPlace:
    def __init__(self, gua_dict: list[int]):
        validate_gua_dict(gua_dict)  # ✅ 使用验证器进行校验
        self.gua = AttrFuncDict(**gua_dict)
        expend_dict = get_time_info(gua_dict)
        self.gua.update(expend_dict)

    @classmethod
    def from_gc_idx(cls, gc_idx: int, title=None):
        m, dg, dz, gua, biangua = GuaCombination.from_index5(gc_idx)
        gua_dict = {'m': m, 'dg': dg, 'd': dz, 'gua': gua, 'biangua': biangua,
                    'title': title if title else 'default title'}
        return cls(gua_dict)

    @classmethod
    def from_params(cls, coinNum:str, timeStr='', solartime=None, title=None):
        '''注意coinNum默认中间没有空格分割，硬币的顺序是:123456,如果用空格/连字符/句号分割，代表从6-5-4-3-2-1'''
        gua_dict = build_dict(coinNum, timeStr, solartime, title=title)
        return cls(gua_dict)

    def _place(self, is_contain_gan=False, skip=True)->tuple[str, list[list[str]]]:
        '''
        :param is_contain_gan:排盘是否包含天干？
        :param skip:只标明世应，跳过间爻&边缘
        :return:
        '''

        def get_yao(row, col, space=''):
            # 注意：这里的 gua.zhi gua.gan都是经过掩码的。
            zhi = self.gua.zhi[row][col]
            if isinstance(zhi, int) and zhi != -1:
                if is_contain_gan:
                    wx_idx = ZHI_TO_WX[zhi]
                    yao = LIU_QIN[(5 + wx_idx - self.gua.wx) % 5] + GAN[self.gua.gan[row][col]] + ZHI[zhi] + WX[wx_idx]
                else:
                    yao = family[zhi % 12]
                    # wx_idx = ZHI_TO_WX[zhi];assert LIU_QIN[(5+wx_idx-self.gua.wx)%5]+ZHI[zhi]+WX[wx_idx]==yao
                return yao
            else:
                return space

        gua_instance = GuaModel(self.gua.gua)
        family = gua_instance.get_palace12()
        gua_full_name = gua_instance.get_full_gua_name()
        self_other_list = gua_instance.get_self_other_list(skip=skip)

        head_title = f'占题：{self.gua.title if "title" in self.gua else "无标题"}'
        solar_time = f'公历时间：{self.gua.current_time if self.gua.get("current_time") else build_event_time(self.gua)}'
        current_time = f'当前时间：{self.gua.time_info}'

        condition = self.gua.biangua is not None and \
                    self.gua.biangua != self.gua.gua and \
                    self.gua.biangua != 64
        gua_name_line = ' ' * 6 + GuaModel(self.gua['biangua']).get_full_gua_name() if condition else ''
        text = head_title + '\n' + solar_time + '\n' + current_time + '\n' + gua_full_name + gua_name_line + '\n'

        result_excel = [
            [head_title],
            [solar_time],
            [current_time],
            ['', '', gua_full_name, '', gua_name_line.strip()]
        ]

        sign = ["×", '′', '″', "○"]

        if all(m == -1 for m in self.gua.zhi[2]):
            cent = 0
        else:
            cent = 10 if is_contain_gan else 8
        # print('使用的六亲地支，family', family)
        # print('伏藏的地支数，self.gua.zhi[2]', self.gua.zhi[2])

        for i in range(6):
            n = self.gua.coinNumLst[i]
            lst = [self.gua.animals[i],
                   get_yao(2, i, ' ' * cent),
                   get_yao(0, i) + sign[n],
                   self_other_list[i] or ' ' * 2,
                   '' if self.gua.zhi[1][i] == -1 else get_yao(1, i) + sign[(n + 3) // 3]]
            line = ' '.join(lst)
            text += line + '\n'
            result_excel.append(lst)

        return text, result_excel

    def place(self, is_contain_gan=False, skip=True,output=False,mode='text'):
        text, table = self._place(is_contain_gan, skip)
        if mode=='text':
            result = text
        elif mode=='table':
            result = table
        else:
            raise ValueError('mode must be text or table')
        if output:print(result)
        return result



if __name__ == '__main__':
    from test_cases import gua_dicts
    lyp = LiuYaoPlace(gua_dicts[0])
    # lyp = LiuYaoPlace.from_gc_idx(1235167)
    print(lyp.gua)
    lyp.place(is_contain_gan=True,output=True)
    print(lyp.gua)  # 排盘期间，AttrFuncDict内置的core.lazy_load，惰性加载启动了。所以多出来多个键值。
